home *** CD-ROM | disk | FTP | other *** search
- /*
- * CSignedObject.c
- * Copyright © 1993 Apple Computer Inc.
- * All Rights Reserved
- *
- * Extend Digital Signature capability
- * to individual Think Class Library objects.
- */
- #include "CSignedObject.h"
- #include <CDataFile.h>
- #include <Exceptions.h>
- #include <OCEErrors.h>
-
- /*
- * This is written to, and read from,
- * files by the WriteSignature and
- * ReadSignature methods.
- */
- typedef struct SignatureHeader {
- OSType magicCookie;
- Size signatureSize;
- } SignatureHeader;
- /*
- * kMagicCookie is stored in the signature
- * header to help certify that we are actually
- * reading a signature that we wrote.
- */
- #define kMagicCookie gestaltDigitalSignatureVersion
-
- void
- CSignedObject::ISignedObject(void)
- {
- inherited::ISignature();
- itsSignature = NULL;
- itsSignatureSize = 0;
- }
-
- void
- CSignedObject::Dispose(void)
- {
- DisposeSignature();
- inherited::Dispose();
- }
-
- Size
- CSignedObject::SignPrepare(
- const FSSpec *signerFile,
- ConstStr255Param prompt
- )
- {
- itsSignatureSize = inherited::SignPrepare(
- signerFile,
- prompt
- );
- return (itsSignatureSize);
- }
-
- /*
- * Sign creates a signature for the data recently processed
- * by ProcessData. The current signature is used, if it
- * still exists. Sign deletes the context if it fails, but
- * retains it on success so the application can extract
- * certificate information.
- */
- void
- CSignedObject::Sign(
- SIGStatusProcPtr statusProc
- )
- {
- Boolean userCreatedSignature;
- Str255 msg1;
- Str255 msg2;
-
- if ((userCreatedSignature = HasSignature()) == FALSE)
- NewSignature();
- if (statusProc == gSIGStatusProc) {
- GetIndString(msg1, STRn_SIGStatusProc, kStatusSignString);
- GetIndString(msg2, STRn_SIGStatusProc, kStatusDataString);
- InitDefaultStatusProc(msg1, msg2);
- }
- TRY {
- FailOSErr(SIGSign(
- gSIGContextPtr,
- itsSignature,
- statusProc
- ));
- }
- CATCH {
- DisposeDefaultStatusProc();
- if (gLastError != kSIGInvalidCredentialErr) {
- DisposeSignerContext();
- if (userCreatedSignature == FALSE)
- DisposeSignature();
- DisposeSignerContext();
- }
- }
- ENDTRY;
- DisposeDefaultStatusProc();
- /*
- * It is the caller's responsibility to
- * dispose of the signature and the
- * context as soon as possible.
- */
- }
-
- /*
- * VerifyPrepare initializes the verification process.
- * The caller must have already loaded the signature into
- * the signature buffer e.g. by reading it from a file.
- * On exit, a context is present.
- */
- void
- CSignedObject::VerifyPrepare(
- SIGStatusProcPtr statusProc
- )
- {
- OSErr status;
- Str255 msg1;
- Str255 msg2;
-
- CheckForSignature();
- NewContext(kSIGVerify);
- if (statusProc == gSIGStatusProc) {
- GetIndString(msg1, STRn_SIGStatusProc, kStatusVerifyString);
- GetIndString(msg2, STRn_SIGStatusProc, kStatusDataString);
- InitDefaultStatusProc(msg1, msg2);
- }
- TRY {
- FailOSErr(SIGVerifyPrepare(
- gSIGContextPtr,
- itsSignature,
- itsSignatureSize,
- statusProc
- ));
- }
- CATCH {
- if (gLastError != kSIGInvalidCredentialErr) {
- DisposeDefaultStatusProc();
- DisposeSignerContext();
- }
- }
- ENDTRY;
- /*
- * Note that a context is present.
- */
- }
-
- /*
- * Finish verifying an object by checking the result
- * of the ProcessData sequence. This will fail with
- * a paramErr if there is no context. It does not
- * delete the context.
- */
- void
- CSignedObject::Verify(void)
- {
- OSErr status;
-
- CheckForContext();
- status = SIGVerify(gSIGContextPtr);
- DisposeDefaultStatusProc();
- if (status != noErr
- && status != kSIGInvalidCredentialErr) {
- /*
- * Note: I haven't been able to get this
- * error, so I'm not sure if ws should
- * keep the context if the credentials
- * are "pending or expired."
- */
- DisposeSignerContext();
- }
- FailOSErr(status);
- }
-
- /*
- * ProcessData is called for all information that is
- * to be signed or verified. Note that it does not
- * move memory. It will fail with a paramErr if
- * there is no context.
- */
- void
- CSignedObject::ProcessData(
- const void *data,
- Size dataSize
- )
- {
- /*
- * While we should call CheckForContext()
- * here, we'll skip it (for speed), hoping
- * that SIGProcessData does the checking
- * or that the error will be caught
- * early in the debugging process.
- */
- FailOSErr(SIGProcessData(
- gSIGContextPtr,
- data,
- dataSize
- ));
- }
-
- /*
- * Dispose of the current signature. Note that
- * we do not clear the signature size.
- */
- void
- CSignedObject::DisposeSignature(void)
- {
- SIGSignaturePtr aSignature;
-
- if ((aSignature = itsSignature) != NULL) {
- itsSignature = NULL;
- DisposePtr(aSignature);
- FailMemError();
- }
- }
-
- /*
- * Return the signature size.
- */
- Size
- CSignedObject::GetSignatureSize(void)
- {
- return (itsSignatureSize);
- }
-
- /*
- * Create a new signature.
- */
- void
- CSignedObject::NewSignature(void)
- {
- if (itsSignatureSize == 0)
- FailOSErr(paramErr);
- DisposeSignature();
- itsSignature = (SIGSignaturePtr) NewPtr(itsSignatureSize);
- FailNIL(itsSignature);
- }
-
- /*
- * Return TRUE if there is a current signature.
- */
- Boolean
- CSignedObject::HasSignature(void)
- {
- return (itsSignature != NULL);
- }
-
- /*
- * Fail if there is no current signature.
- */
- void
- CSignedObject::CheckForSignature(void)
- {
- if (itsSignature == NULL)
- FailOSErr(kSIGNoSignature);
- }
-
- Size
- CSignedObject::CopySignatureToUserBuffer(
- void *buffer,
- Size bufferSize
- )
- {
- CheckForSignature();
- if (bufferSize < itsSignatureSize)
- FailOSErr(paramErr);
- BlockMove(itsSignature, buffer, itsSignatureSize);
- return (itsSignatureSize);
- }
-
- void
- CSignedObject::MakeSignatureFromUserBuffer(
- void *buffer,
- Size bufferSize
- )
- {
- DisposeSignature();
- itsSignatureSize = bufferSize;
- NewSignature();
- BlockMove(buffer, itsSignature, bufferSize);
- }
-
- void
- CSignedObject::WriteSignature(
- CDataFile *aFile
- )
- {
- SignatureHeader signatureHeader;
-
- signatureHeader.magicCookie = kMagicCookie;
- if (HasSignature() == FALSE)
- signatureHeader.signatureSize = 0;
- else {
- signatureHeader.signatureSize = itsSignatureSize;
- }
- aFile->WriteSome(
- (Ptr) &signatureHeader,
- sizeof signatureHeader
- );
- if (signatureHeader.signatureSize != 0) {
- aFile->WriteSome(
- itsSignature,
- signatureHeader.signatureSize
- );
- }
- }
-
- void
- CSignedObject::ReadSignature(
- CDataFile *aFile
- )
- {
- SignatureHeader signatureHeader;
-
- DisposeSignature();
- aFile->ReadSome(
- (Ptr) &signatureHeader,
- sizeof signatureHeader
- );
- if (signatureHeader.magicCookie != kMagicCookie)
- FailOSErr(paramErr);
- itsSignatureSize = signatureHeader.signatureSize;
- if (itsSignatureSize > 0) {
- NewSignature();
- aFile->ReadSome(
- itsSignature,
- itsSignatureSize
- );
- }
- }
-
-
-